package org.bim.view.drag.design.config;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.bim.view.drag.design.api.dto.LoginDTO;
import org.bim.view.drag.design.api.form.MailContent;
import org.bim.view.drag.design.api.vo.TUserVO;
import org.bim.view.drag.design.base.OnlineUserMap;
import org.bim.view.drag.design.constant.CommonConstant;
import org.bim.view.drag.design.constant.MailContentTypeEnum;
import org.bim.view.drag.design.dao.UserMapper;
import org.bim.view.drag.design.entity.TUser;
import org.bim.view.drag.design.exception.BizCommonException;
import org.bim.view.drag.design.util.*;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import tk.mybatis.mapper.entity.Example;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Component
@RequiredArgsConstructor
@Slf4j
public class DesignerLoginService {
    private final UserMapper userMapper;
    private final MailUtils mailUtils;
    private final ServerUtils serverUtils;
    /**
     * 暂时使用过期Map来实现在线用户
     */
    public static final OnlineUserMap onlineUserMap=new OnlineUserMap(30,TimeUnit.MINUTES);

    public boolean checkToken(String token){
        TUserVO one =onlineUserMap.get(token);
        if(one!=null){
            onlineUserMap.put(token,one);
            return true;
        }
       throw new BizCommonException("未授权",401);
    }
    public void logout(String token){
        onlineUserMap.remove(token);
    }
    private String createUid(){
       return UUID.randomUUID().toString().replace("-", "");
    }

    public TUserVO login(LoginDTO dto) {
        Example example = new Example(TUser.class);
        example.selectProperties("id","account","name","email","role");
        example.createCriteria()
                .andEqualTo("account", dto.getAccount())
                .andEqualTo("password", dto.getPassword());
        Example.Criteria emailCriteria = example.createCriteria()
                .andEqualTo("email", dto.getAccount())
                .andEqualTo("password", dto.getPassword());
        example.or(emailCriteria);
        TUser tUser = userMapper.selectOneByExample(example);
        AssertUtil.isTrue(tUser!=null,"用户名或密码错误");
        TUserVO userVO = new TUserVO();
        BeanUtils.copyProperties(tUser,userVO);
        String token =createUid();
        userVO.setToken(token);
        onlineUserMap.put(token,userVO);
        return userVO;
    }

    public void register(TUser user){
        Example example =new Example(TUser.class);
        example.createCriteria().andEqualTo("account",user.getAccount());
        int isAccountExist = userMapper.selectCountByExample(example);
        AssertUtil.isTrue(isAccountExist==0 ,"账号已存在");
        Example example1 =new Example(TUser.class);
        example1.createCriteria().andEqualTo("email",user.getEmail());
        int isEmailExist = userMapper.selectCountByExample(example1);
        AssertUtil.isTrue(isEmailExist==0,"邮箱已存在");
        user.setRole(0);
        user.setName(user.getAccount());
        // TODO 后续需要邮箱验证
        userMapper.insertSelective(user);
    }

    /**
     * 发送邮件
     *
     * @param email
     * @param user
     * @return
     */
    public boolean sendMail(String email, TUser user) throws BizCommonException {
        //校验邮箱
        if (!email.equals(user.getEmail())) {
            throw new BizCommonException("The current email address is not match user email address");
        }

        Map<String, Object> content = new HashMap<String, Object>();
        content.put("username", user.getAccount());
        content.put("host", serverUtils.getHost());
        content.put("token", "ddddd");

        MailContent mailContent = MailContent.MailContentBuilder.builder()
                .withSubject("[BIM-VIEW]用户激活")
                .withTo(user.getEmail())
                .withMainContent(MailContentTypeEnum.TEMPLATE)
                .withTemplate(CommonConstant.USER_ACTIVATE_EMAIL_TEMPLATE)
                .withTemplateContent(content)
                .build();

        mailUtils.sendMail(mailContent, null);
        return true;
    }
}
